package me.ezitku.base.PrefHelper

import android.content.Context
import me.ezitku.base.BaseApplication.Companion.context
import java.lang.ClassCastException
import java.lang.Exception
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty


//var prefName = "AppPref"
//
//var localDukkanid by Preference("")
//
//var localDukkanguid by Preference("")
//
//var localUserName by Preference("")
//
//var localPassword by Preference("")
//
//var localToken by Preference("")
//var localUserId by Preference(-1L)
//
//var localLastBillSerialNum by Preference(1000)


//==================Encryption============================
private fun encrypt(data: String): String {
    return try {
        AES.encrypt("123456", data)
    } catch (e: Exception) {
        ""
    }

}

private fun decrypt(data: String): String {
    return try {
        AES.decrypt("123456", data)
    } catch (e: Exception) {
        ""
    }

}
//================================================

class Preference<T>(val default: T, val isCrypt: Boolean = true, val key: String = "", val fileName: String = "AppPref") : ReadWriteProperty<Any?, T> {
    val prefs by lazy { context.getSharedPreferences(fileName, Context.MODE_PRIVATE) }
    override operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
        if (key.isEmpty()) {
            return findPreference(property.name, default)
        } else {
            return findPreference(key, default)
        }

    }

    override operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        if (key.isEmpty()) {
            putPreference(property.name, value)
        } else {
            putPreference(key, value)
        }

    }

    private fun <U> findPreference(name: String, default: U): U = with(prefs) {
        var res: Any
        try {
            res = when (default) {
                is Long -> getLong(name, default)
                is String -> {
                    val result = getString(name, "")
                    if (result.isEmpty()) {
                        return default
                    }
                    if (isCrypt)
                        decrypt(result)
                    else
                        result
                }

                is Int -> getInt(name, default)
                is Boolean -> getBoolean(name, default)
                is Float -> getFloat(name, default)
                else -> throw IllegalArgumentException("This type can be saved into Preferences")
            }
        }catch (e:ClassCastException){
            val dd = getString(name, "")
            res = dd.toInt()
        }catch (e:Exception){
            println(e.message)
            res = ""
        }


        res as U
    }

    private fun <U> putPreference(name: String, value: U) = with(prefs.edit()) {
        when (value) {
            is Long -> putLong(name, value)
            is String -> {
                val putValue = if (isCrypt) encrypt(value) else value
                putString(name, putValue)
            }
            is Int -> putInt(name, value)
            is Boolean -> putBoolean(name, value)
            is Float -> putFloat(name, value)
            else -> throw IllegalArgumentException("This type can be saved into Preferences")
        }.apply()
    }
}